package com.cu.employmentmanagementsystem.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;



@Configuration
public class RedisCacheConfig
{
    @Value("${spring.redis.host}")
    private String hostName;
    @Value("${spring.redis.port}")
    private int port;
//    @Value("${spring.redis.password}")
//    private String password;

    @Value("${spring.redis.database.user-token-db}")
    private int databaseUserToken;
    @Value("${spring.redis.database.email-code-db}")
    private int databaseEmailCode;
    @Value("${spring.redis.database.user-ip-use-frequency-db}")
    private int databaseUserIPUseFrequency;
    @Value("${spring.redis.database.user-ip-use-times-db}")
    private int databaseUserIPUseTimes;
    @Value("${spring.redis.database.captcha-db}")
    private int databaseCaptcha;

    @Value("${spring.redis.lettuce.pool.max-active}")
    private int maxTotal; //连接池中最大连接数
    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxIdle; //最大空闲连接数
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private int minIdle; //最小空闲连接数
    @Value("${spring.redis.lettuce.pool.max-wait}")
    private int maxWait; //当池内没有可用的连接时，最大等待时间

    public static final String REDIS_TEMPLATE_EMAIL_CODE = "Email_Code_RedisTemplate";
    public static final String REDIS_TEMPLATE_USER_IP_USE_FREQUENCY = "User_IP_Use_Frequency_RedisTemplate";
    public static final String REDIS_TEMPLATE_USER_IP_USE_TIMES = "User_IP_Use_Times_RedisTemplate";
    public static final String REDIS_TEMPLATE_CAPTCHA = "Captcha_RedisTemplate";
    public static final String REDIS_TEMPLATE_USER_TOKEN = "User_Token_RedisTemplate";

    @Bean(REDIS_TEMPLATE_USER_TOKEN)
    public RedisTemplate<String, String> userTokenRedisTemplate()
    {
        return getRedisTemplate(databaseUserToken);
    }
    @Bean(REDIS_TEMPLATE_EMAIL_CODE)
    public RedisTemplate<String, String> emailCodeRedisTemplate()
    {
        return getRedisTemplate(databaseEmailCode);
    }

    @Bean(REDIS_TEMPLATE_USER_IP_USE_FREQUENCY)
    public RedisTemplate<String, String> frequencyRedisTemplate()
    {
        return getRedisTemplate(databaseUserIPUseFrequency);
    }

    @Bean(REDIS_TEMPLATE_USER_IP_USE_TIMES)
    public RedisTemplate<String, String> timesRedisTemplate()
    {
        return getRedisTemplate(databaseUserIPUseTimes);
    }

    @Bean(REDIS_TEMPLATE_CAPTCHA)
    public RedisTemplate<String, String> captchaRedisTemplate()
    {
        return getRedisTemplate(databaseCaptcha);
    }

    private RedisTemplate<String, String> getRedisTemplate(int database)
    {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate();

        redisTemplate.setConnectionFactory(getRedisConnectionFactory(database));
        /** key采用StringRedisSerializer序列化 */
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setValueSerializer(RedisSerializer.string());
        /** 设置hash key和value的序列化方式 */
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    private RedisConnectionFactory getRedisConnectionFactory(int database)
    {
        /** 单机配置 + 客户端配置 = jedis连接工厂 */
        JedisConnectionFactory jedisConnectionFactory =
                new JedisConnectionFactory(getRedisStandaloneConfig(database), getJedisClientConfig());
        jedisConnectionFactory.afterPropertiesSet();

        return jedisConnectionFactory;
    }

    private RedisStandaloneConfiguration getRedisStandaloneConfig(int database)
    {
        RedisStandaloneConfiguration redisStandaloneConfig = new RedisStandaloneConfiguration();
        redisStandaloneConfig.setHostName(hostName);
        redisStandaloneConfig.setPort(port);
//        redisStandaloneConfig.setPassword(RedisPassword.of(password));
        redisStandaloneConfig.setDatabase(database);
        return redisStandaloneConfig;
    }

    private JedisClientConfiguration getJedisClientConfig()
    {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxTotal); //连接池中最大连接数
        jedisPoolConfig.setMaxIdle(maxIdle); //最大空闲连接数
        jedisPoolConfig.setMinIdle(minIdle); //最小空闲连接数
        //当池内没有可用的连接时，最大等待时间
        jedisPoolConfig.setMaxWait(Duration.ofMillis(maxWait));
        //在获取连接时是否检查有效性, 默认false
//        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        //在归还连接时是否检查有效性, 默认false
//        jedisPoolConfig.setTestOnReturn(testOnReturn);

        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpccb =
                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        jpccb.poolConfig(jedisPoolConfig);

        return jpccb.build();
    }
}
